package ndk.caro.gameplays;

import java.util.Random;

import android.content.Intent;
import android.graphics.Point;
import android.util.Log;
import android.view.MotionEvent;
import ndk.caro.activities.myWinnerActivity;
import ndk.caro.algorithms.myAlgorithms;
import ndk.caro.tools.myTool;
import ndk.caro.views.myCaroView;
import ndk.caro.views.myCaroView.TouchMode;

public class myCaroGame {
	public static int iGAME_SIZE = 20;
	public static int iGAME_CENTER_ARRAY_PIECE = iGAME_SIZE / 2;
	private static Player ePlayer;
	public boolean bChangePlayer = true;
	public Boolean bAllowTouchBluetooth = true;
	public myAlgorithms mAlgorithms;
	public int iWinner = myPiece.NONE;
	private myPiece[][] mPiece;
	public myCaroView mCaroView;
	
	public int getWinner() {
		return iWinner;
	}

	public static Player getPlayer() {
		return ePlayer;
	}

	public static void setPlayer(Player ePlayer) {
		myCaroGame.ePlayer = ePlayer;
	}

	public myCaroGame(myCaroView mCaroview) {
		this.mCaroView = mCaroview;
	}

	public myPiece getPiece(int iIndex, int jIndex) {
		return mPiece[iIndex][jIndex];
	}

	public void setPiece(int iIndex, int jIndex, int iValue) {
		this.mPiece[iIndex][jIndex].setValue(iValue);
	}

	public myPiece getLeftTopPiece() {
		return mPiece[0][0];
	}

	public myPiece getRightBottomPiece() {
		return mPiece[myCaroGame.iGAME_SIZE - 1][myCaroGame.iGAME_SIZE - 1];
	}

	private void initPieces() {
		this.mPiece = new myPiece[myCaroGame.iGAME_SIZE][myCaroGame.iGAME_SIZE];
		for (int i = 0; i < myCaroGame.iGAME_SIZE; i++) {
			for (int j = 0; j < myCaroGame.iGAME_SIZE; j++) {
				this.mPiece[i][j] = new myPiece(i, j);
				this.mPiece[i][j].setValue(myPiece.NONE);
				this.mPiece[i][j].setFourAngle();
			}
		}
		if(ePlayer == Player.CPU) {
			this.mAlgorithms = new myAlgorithms(this);
		}
	}

	public void NewGame() {
		if (ePlayer == Player.CPU) {
			this.initPieces();

			this.mAlgorithms.iEnd = myPiece.NONE;
			myAlgorithms.MaxDepth = 20;
			this.mAlgorithms.iCurrPlayer = myPiece.iOPLAYER;
			this.mAlgorithms.TScore = new int[] { 0, 1, 9, 85, 769 };
			this.mAlgorithms.KScore = new int[] { 0, 2, 28, 256, 2308 };
		} else if (ePlayer == Player.PVSP || ePlayer == Player.BLUE) {
			this.initPieces();
		} 

	}

	// Kiem tra ben nao thang
	public int CheckEnd(int rw, int cl) {
		boolean bOPLAYER, bXPLAYER;
		int r = 1, c = 1;
		int i;

		// Kiem tra tren hang...
		while (c <= myCaroGame.iGAME_SIZE - 6) {
			bOPLAYER = true;
			bXPLAYER = true;
			for (i = 0; i < 5; i++) {
				if (this.mPiece[rw][c + i].getValue() != myPiece.iOPLAYER) {
					bOPLAYER = false;
				}
				if (this.mPiece[rw][c + i].getValue() != myPiece.iXPLAYER) {
					bXPLAYER = false;
				}
			}

			if (bOPLAYER
					&& (this.mPiece[rw][c - 1].getValue() != myPiece.iXPLAYER || this.mPiece[rw][c + 5]
							.getValue() != myPiece.iXPLAYER)) {
				return myPiece.iOPLAYER;
			}
			if (bXPLAYER
					&& (this.mPiece[rw][c - 1].getValue() != myPiece.iOPLAYER || this.mPiece[rw][c + 5]
							.getValue() != myPiece.iOPLAYER)) {
				return myPiece.iXPLAYER;
			}
			c++;
		}

		// Kiem tra tren cot...
		while (r <= myCaroGame.iGAME_SIZE - 6) {
			bOPLAYER = true;
			bXPLAYER = true;
			for (i = 0; i < 5; i++) {
				if (this.mPiece[r + i][cl].getValue() != myPiece.iOPLAYER) {
					bOPLAYER = false;
				}
				if (this.mPiece[r + i][cl].getValue() != myPiece.iXPLAYER) {
					bXPLAYER = false;
				}
			}
			if (bOPLAYER
					&& (this.mPiece[r - 1][cl].getValue() != myPiece.iXPLAYER || this.mPiece[r + 5][cl]
							.getValue() != myPiece.iXPLAYER)) {
				return myPiece.iOPLAYER;
			}
			if (bXPLAYER
					&& (this.mPiece[r - 1][cl].getValue() != myPiece.iOPLAYER || this.mPiece[r + 5][cl]
							.getValue() != myPiece.iOPLAYER)) {
				return myPiece.iXPLAYER;
			}
			r++;
		}

		// Kiem tra tren duong cheo xuong.
		r = rw;
		c = cl;
		// Di chuyen den dau duong cheo xuong.
		while (r > 1 && c > 1) {
			r--;
			c--;
		}

		while (r <= myCaroGame.iGAME_SIZE - 6 && c <= myCaroGame.iGAME_SIZE - 6) {
			bOPLAYER = true;
			bXPLAYER = true;
			for (i = 0; i < 5; i++) {
				if (this.mPiece[r + i][c + i].getValue() != myPiece.iOPLAYER) {
					bOPLAYER = false;
				}
				if (this.mPiece[r + i][c + i].getValue() != myPiece.iXPLAYER) {
					bXPLAYER = false;
				}
			}
			if (bOPLAYER
					&& (this.mPiece[r - 1][c - 1].getValue() != myPiece.iXPLAYER || this.mPiece[r + 5][c + 5]
							.getValue() != myPiece.iXPLAYER)) {
				return myPiece.iOPLAYER;
			}
			if (bXPLAYER
					&& (this.mPiece[r - 1][c - 1].getValue() != myPiece.iOPLAYER || this.mPiece[r + 5][c + 5]
							.getValue() != myPiece.iOPLAYER)) {
				return myPiece.iXPLAYER;
			}
			r++;
			c++;
		}

		// Kiem tra duong cheo len...
		r = rw;
		c = cl;
		// Di chuyen den dau duong cheo len...
		while (r <= myCaroGame.iGAME_SIZE - 2 && c > 1) {
			r++;
			c--;
		}
		while (r >= 5 && c <= myCaroGame.iGAME_SIZE - 6) {
			bOPLAYER = true;
			bXPLAYER = true;
			for (i = 0; i < 5; i++) {
				if (this.mPiece[r - i][c + i].getValue() != myPiece.iOPLAYER) {
					bOPLAYER = false;
				}
				if (this.mPiece[r - i][c + i].getValue() != myPiece.iXPLAYER) {
					bXPLAYER = false;
				}
			}
			if (bOPLAYER
					&& (this.mPiece[r + 1][c - 1].getValue() != myPiece.iXPLAYER || this.mPiece[r - 5][c + 5]
							.getValue() != myPiece.iXPLAYER)) {
				return myPiece.iOPLAYER;
			}
			if (bXPLAYER
					&& (this.mPiece[r + 1][c - 1].getValue() != myPiece.iOPLAYER || this.mPiece[r - 5][c + 5]
							.getValue() != myPiece.iOPLAYER)) {
				return myPiece.iXPLAYER;
			}
			r--;
			c++;
		}

		return myPiece.NONE;
	}

	public void HandleTouchUp(MotionEvent e) {
		if (ePlayer == Player.CPU) {
			HandleTouchUpCPU(e);
		} else if (ePlayer == Player.PVSP) {
			HandleTouchUpPvsP(e);
		}else if(ePlayer == Player.BLUE) {
			
				if(this.bAllowTouchBluetooth) {
					HandleTouchUpPvsBlue(e);					
					//Log.i("ndk", "NDK!");
				}
		}
	}
	
	public void HandleTouchUpPvsBlue(MotionEvent e){
		Point p;
		this.mCaroView.setPointAfterTouchDisplay(e.getX(), e.getY());
		p = this.mCaroView.getPointAfterTouchForPiece();
		
		int a = this.getPiece(p.x, p.y).getValue() ;
		this.HandlePointToCaroView(p);
		if (a == myPiece.NONE ) {
			this.mCaroView.actMain.sendMessage(myTool.returnStringFromPointF(p));
		}
		
	}
	
    public void HandlePointToCaroView(Point p) {
    	if (this.getPiece(p.x, p.y).getValue() == myPiece.NONE ) {
    	
    		int iFlag = myPiece.NONE;
			if (this.bChangePlayer) {
				iFlag = myPiece.iOPLAYER;
			} else {
				iFlag = myPiece.iXPLAYER;
			} 
			
			this.bAllowTouchBluetooth = false;
			
			this.setPiece(p.x, p.y, iFlag);

			
			mCaroView.arrLPieceSelected.add(this.getPiece(p.x, p.y)
					.getLocation());
			this.mCaroView.setTouched(true);
			mCaroView.setTouchmode(TouchMode.DEFAULT);
			
			mCaroView.invalidate();
			
			this.bChangePlayer = !this.bChangePlayer;

			if ((this.iWinner = this.CheckEnd(p.x, p.y)) != myPiece.NONE) {
				this.DisplayWinner(this.iWinner);
			}
		}
    }
	
	public void HandleTouchUpPvsP(MotionEvent e) {
		if (this.iWinner == myPiece.NONE) {
			int iFlag = myPiece.NONE;
			if (bChangePlayer) {
				iFlag = myPiece.iOPLAYER;
			} else {
				iFlag = myPiece.iXPLAYER;
			}

			this.mCaroView.setTouched(true);
			Point p;
			this.mCaroView.setPointAfterTouchDisplay(e.getX(), e.getY());
			p = this.mCaroView.getPointAfterTouchForPiece();

			if (getPiece(p.x, p.y).getValue() == myPiece.NONE) {
				setPiece(p.x, p.y, iFlag);

				mCaroView.arrLPieceSelected.add(getPiece(p.x, p.y)
						.getLocation());
				mCaroView.setTouchmode(TouchMode.DEFAULT);
				mCaroView.invalidate();

				this.bChangePlayer = !this.bChangePlayer;

				if ((this.iWinner = this.CheckEnd(p.x, p.y)) != myPiece.NONE) {
					this.DisplayWinner(this.iWinner);
				}
			}
		}
	}

	public void DisplayWinner(int iWinner) {
		Intent intent = new Intent(this.mCaroView.actMain,
				myWinnerActivity.class);
		intent.setAction(iWinner + "");
		// intent.putExtra("win", iWinner);
		this.mCaroView.actMain.startActivity(intent);
	}

	public void HandleTouchUpCPU(MotionEvent e) {
		Random rand = new Random();
		Point node;
		int r;
		int c;
		int count;

		count = rand.nextInt(4);
		Point p;
		this.mCaroView.setPointAfterTouchDisplay(e.getX(), e.getY());
		p = this.mCaroView.getPointAfterTouchForPiece();

		this.mCaroView.setTouched(true);

	

		if (getPiece(p.x, p.y).getValue() == myPiece.NONE) {
			r = p.x;
			c = p.y;

			node = new Point();
			// nguoi choi di co.
			if (mAlgorithms.iCurrPlayer == myPiece.iOPLAYER
					&& mAlgorithms.iEnd == myPiece.NONE) {
				setPiece(r, c, mAlgorithms.iCurrPlayer);

				mCaroView.arrLPieceSelected.add(getPiece(r, c).getLocation());
				mCaroView.setTouchmode(TouchMode.DEFAULT);
				mCaroView.invalidate();
				mAlgorithms.iCurrPlayer = myPiece.iXPLAYER;

				mAlgorithms.iEnd = CheckEnd(r, c);
				if (mAlgorithms.iEnd != myPiece.NONE) {
					DisplayWinner(mAlgorithms.iEnd);
				}
			}
		}

		if (mAlgorithms.iCurrPlayer == myPiece.iXPLAYER
				&& mAlgorithms.iEnd == myPiece.NONE) { // Tim nuoc
														// di chien
														// thang.
			mAlgorithms.EBoard.ResetBoard();

			mAlgorithms.GetGenResult();

			if (mAlgorithms.bWin) {
				node = mAlgorithms.WinMoves[1];
			} else {
				mAlgorithms.EBoard.ResetBoard();
				mAlgorithms.EvalueGomokuBoard(myPiece.iXPLAYER);
				node = mAlgorithms.EBoard.GetMaxNode();
				if (!mAlgorithms.bLose) {
					for (int i = 0; i < count; i++) {
						mAlgorithms.EBoard.Board[node.x][node.y] = 0;
						node = mAlgorithms.EBoard.GetMaxNode();
					}
				}
			} // May di quan.
			r = node.x;
			c = node.y;
			setPiece(r, c, mAlgorithms.iCurrPlayer);
			mCaroView.arrLPieceSelected.add(getPiece(r, c).getLocation());

			//mCaroView.invalidate();
			mAlgorithms.iCurrPlayer = myPiece.iOPLAYER;
			// Kiem tra tran dau ket thuc chua ?
			mAlgorithms.iEnd = CheckEnd(r, c);
			if (mAlgorithms.iEnd != myPiece.NONE) {
				DisplayWinner(mAlgorithms.iEnd);
			}
		}
	}

	public enum Player {
		CPU, PVSP, BLUE
	}
}
